package grpc_proxy_router

import (
	"fmt"
	"gitee.com/zhoulvvv/my_go_gateway/dao"
	"gitee.com/zhoulvvv/my_go_gateway/grpc_proxy_middleware"
	"gitee.com/zhoulvvv/my_go_gateway/reverse_proxy"
	"gitee.com/zhoulvvv/my_go_gateway/services"
	"github.com/e421083458/grpc-proxy/proxy"
	"github.com/gin-gonic/gin"
	"google.golang.org/grpc"
	"log"
	"net"
	"net/http/httptest"
)

var grpcServerList = []*warpGrpcServer{}

type warpGrpcServer struct {
	Addr string
	*grpc.Server
}

func GrpcServerRun() {
	// 获取GRPC服务信息
	grpcServiceList := services.ServiceManagerServiceHandler.GetGrpcServiceList(nil)
	for _, serviceItem := range grpcServiceList {
		tempItem := serviceItem
		// 使用协程启动GRPC服务
		go func(serviceInfo *dao.ServiceDetail) {
			addr := fmt.Sprintf(":%d", serviceInfo.GRPCRule.Port)
			c, _ := gin.CreateTestContext(httptest.NewRecorder())
			// 获取负载均衡器
			rb, err := services.LoadBalancerHandler.GetLoadBalancer(c, serviceInfo)
			if err != nil {
				log.Fatalf(" [ERROR] grpc_proxy_run【获取负载均衡器失败】 port：%v err：%v\n", addr, err)
			}
			lis, err := net.Listen("tcp", addr)
			if err != nil {
				log.Fatalf(" [ERROR] grpc_proxy_run net.Listen port：%v err：%v\n", addr, err)
			}
			// 获取grpc的代理处理器
			grpcProxyHandler := reverse_proxy.NewGrpcLoadBalanceHandler(rb)
			s := grpc.NewServer(
				grpc.ChainStreamInterceptor(
					grpc_proxy_middleware.GRPCFlowCountModeMiddleware(serviceInfo),        // 流量统计中间件
					grpc_proxy_middleware.GRPCFlowLimitModeMiddleware(serviceInfo),        // 服务端和客户端限流中间件
					grpc_proxy_middleware.GRPCJwtOAuthTokenModeMiddleware(serviceInfo),    // token 校验中间件
					grpc_proxy_middleware.GRPCJwtFlowCountModeMiddleware(serviceInfo),     // 租户流量统计
					grpc_proxy_middleware.GRPCJwtFlowLimitModeMiddleware(serviceInfo),     // 租户限流
					grpc_proxy_middleware.GRPCWhiteListModeMiddleware(serviceInfo),        // 白名单中间件
					grpc_proxy_middleware.GRPCBlackListModeMiddleware(serviceInfo),        // 黑名单中间件
					grpc_proxy_middleware.GRPCMetadataTransferModeMiddleware(serviceInfo), // metadata 转换中间件
				),
				grpc.CustomCodec(proxy.Codec()),
				grpc.UnknownServiceHandler(grpcProxyHandler))
			log.Printf(" [INFO] grpc_proxy_run:%v\n", addr)
			grpcServerList = append(grpcServerList, &warpGrpcServer{Addr: addr, Server: s})
			if err := s.Serve(lis); err != nil {
				log.Fatalf(" [ERROR] grpc_proxy_run s.Serve(lis) port：%v err：%v\n", addr, err)
			}
		}(tempItem)
	}
}

func GrpcServerStop() {
	for _, grpcServer := range grpcServerList {
		grpcServer.GracefulStop()
		log.Printf(" [INFO] grpc_proxy_stop stopped port %v\n", grpcServer.Addr)
	}
}
